package net.coding.li709.materialrefresher;

import com.google.inject.Inject;
import lombok.NonNull;
import net.coding.li709.materialrefresher.command.AddSpawnBoxCommand;
import net.coding.li709.materialrefresher.command.TestCommand;
import net.coding.li709.materialrefresher.keys.FlanData;
import net.coding.li709.materialrefresher.keys.FlanDataManipulatorBuilder;
import net.coding.li709.materialrefresher.keys.FlanKeys;
import net.coding.li709.materialrefresher.keys.ImmutableFlanData;
import net.coding.li709.materialrefresher.listener.GameListener;
import net.coding.li709.materialrefresher.manage.BoxSpawnManager;
import net.coding.li709.materialrefresher.manage.GiftManager;
import net.coding.li709.serverbase.utils.ConfigUtils;
import org.slf4j.Logger;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.args.GenericArguments;
import org.spongepowered.api.command.spec.CommandSpec;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.data.DataRegistration;
import org.spongepowered.api.data.key.Key;
import org.spongepowered.api.data.value.mutable.Value;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
import org.spongepowered.api.event.world.LoadWorldEvent;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.text.Text;

import java.nio.file.Path;
import java.util.Optional;

@Plugin(
        id = "materialrefresher",
        name = "MaterialRefresher",
        version = "1.0.0"
)
public class MaterialRefresher {

    public static final String ID="materialrefresher";

    @NonNull
    @lombok.Getter
    private static MaterialRefresher instance = null;
    @Inject
    public Logger logger;

    @Inject
    @ConfigDir(sharedRoot = false)
    private Path configDir;

    public MaterialRefresher() {
        if (instance != null) throw new IllegalStateException("Instance already exists!");

        instance = this;
    }

    public static Logger getLogger() {
        return instance.logger;
    }

    /**
     * 加载不同世界时，加载不同世界的生成点配置。
     * 只有在加载世界后，还未加载实体的间隔中，加载配置，才能正确初始化生成点
     * @param event
     */
    @Listener
    public void loadWorldEvent(LoadWorldEvent event){
        BoxSpawnManager.loadWorldSpawn(event.getTargetWorld().getName());
    }
    @Listener
    public void onServerStart(GameStartedServerEvent event) {
       registerCommand();
       GiftManager.load();
       BoxSpawnManager.init();
    }

    @Listener
    public void onPreInit(GamePreInitializationEvent event) {
        ConfigUtils.init(MaterialRefresher.ID,configDir);


        //提前初始化
        Sponge.getEventManager().registerListeners(this, new GameListener());

        Key<Value<Boolean>> isSpawn = FlanKeys.IS_SPAWN;

        Optional<PluginContainer> pluginContainer = Sponge.getPluginManager().fromInstance(this);
        PluginContainer pluginContainer1 = pluginContainer.get();
        DataRegistration.builder()
                .dataClass(FlanData.class)
                .immutableClass(ImmutableFlanData.class)
                .builder(new FlanDataManipulatorBuilder())
                .manipulatorId("materialrefresher:FlanData")
                .dataName("Custom FlanData")
                .buildAndRegister(pluginContainer1);
    }

    private void registerCommand() {
        CommandSpec addSpawnLocCmd = CommandSpec.builder().arguments(
                GenericArguments.onlyOne(GenericArguments.string(Text.of("locName"))),
                GenericArguments.onlyOne(GenericArguments.string(Text.of("boxName"))),
                GenericArguments.onlyOne(GenericArguments.integer(Text.of("minSecond"))),
                GenericArguments.onlyOne(GenericArguments.integer(Text.of("maxSecond")))
                )
                .description(Text.of("添加生成宝箱地点"))
                .executor(new AddSpawnBoxCommand())
                .build();

        CommandSpec testCmd = CommandSpec.builder().arguments(
                GenericArguments.onlyOne(GenericArguments.string(Text.of("locName")))
        )
                .description(Text.of("测试"))
                .executor(new TestCommand())
                .build();


        Sponge.getCommandManager().register(this, addSpawnLocCmd,  "box");
        Sponge.getCommandManager().register(this, testCmd,  "test");
    }
}
